package com.yfbao.web.gateway.router;

import cn.hutool.core.util.StrUtil;
import com.yfbao.web.gateway.config.OpsUrlConfig;
import com.yfbao.web.gateway.ops.AuthService;
import com.yfbao.web.gateway.vo.TokenResponseVo;
import lombok.extern.slf4j.Slf4j;
    import okhttp3.*;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Set;

// SignatureInterceptor.java
//@Component
@Slf4j
public class TokenInterceptor implements Interceptor {

    private Set<String> whiteListUrls = OpsUrlConfig.witheUrls;
    private final AuthService authService;

    public TokenInterceptor(AuthService authService ) {
        this.authService = authService;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        // 1. 白名单检查
        if (isWhiteListRequest(request)) {
            log.info("白名单请求，跳过Token检查: {}", request.url());
            return chain.proceed(request);
        }

        // 2. Token处理
        Request processedRequest = processToken(request);

        // 3. 执行请求
        Response response = chain.proceed(processedRequest);

        // 4. Token过期处理（401状态码）
        if (response.code() == 401) {
            response.close();
            return handleTokenExpired(chain, request);
        }

        return response;
    }

    /**
     * Token处理逻辑
     */
    private Request processToken(Request request) {
        try {
            String existingToken = getExistingToken(request);

            if (StrUtil.isBlank(existingToken)) {
                // 没有Token，获取新Token
                TokenResponseVo tokenResponse = authService.acquireToken();
                String newToken = tokenResponse.getAccessToken();
                return addTokenToRequest(request, newToken);
            }

            log.debug("使用现有有效Token");
            return request;

        } catch (Exception e) {
            log.error("Token处理失败，使用原始请求", e);
            return request;
        }
    }

    /**
     * 从请求中获取现有Token
     */
    private String getExistingToken(Request request) {
        // 检查多个可能的Token头部
        String[] tokenHeaders = {"token", "Authorization", "X-Auth-Token", "X-Token"};

        for (String header : tokenHeaders) {
            String token = request.header(header);
            if (StrUtil.isNotBlank(token)) {
                // 处理Bearer Token格式
                if (token.startsWith("Bearer ")) {
                    token = token.substring(7);
                }
                return token.trim();
            }
        }
        return null;
    }

    /**
     * 添加Token到请求
     */
    private Request addTokenToRequest(Request request, String token) {
        return request.newBuilder()
                .removeHeader("token") // 移除可能存在的旧Token
                .removeHeader("Authorization")
                .removeHeader("X-Auth-Token")
                .header("Authorization", "Bearer " + token) // 标准格式
                .header("X-Token", token) // 兼容格式
                .header("X-Token-Source", "springboot-auto-refresh")
                .build();
    }

    /**
     * 检查是否为白名单请求
     */
    private boolean isWhiteListRequest(Request request) {
        String path = request.url().encodedPath();
        String method = request.method();

        // 检查完整URL匹配
        String fullUrl = request.url().toString();
        for (String whiteUrl : whiteListUrls) {
            if (fullUrl.contains(whiteUrl)) {
                return true;
            }
        }

        // 检查路径匹配
        for (String whitePath : whiteListUrls) {
            if (path.startsWith(whitePath) || path.equals(whitePath)) {
                return true;
            }
        }

        // 特定方法+路径组合检查
        return isSpecificWhiteListRequest(method, path);
    }

    /**
     * 特定白名单请求检查
     */
    private boolean isSpecificWhiteListRequest(String method, String path) {
        // 健康检查
        if ("GET".equals(method) &&
                (path.equals("/health") || path.equals("/actuator/health"))) {
            return true;
        }

        // 监控端点
        if (path.startsWith("/actuator/") && !path.equals("/actuator/env")) {
            return true;
        }

        // 公开API
        if (path.startsWith("/public/") || path.startsWith("/api/public/")) {
            return true;
        }

        // 认证相关（避免循环认证）
        if (path.contains("/auth/login") || path.contains("/oauth/token")) {
            return true;
        }

        return false;
    }

    /**
     * 处理Token过期
     */
    private Response handleTokenExpired(Chain chain, Request originalRequest) throws IOException {
        log.warn("Token已过期，尝试刷新后重试");

        try {
            // 刷新Token
            String newToken = authService.refreshToken().getAccessToken();

            // 使用新Token重试请求
            Request retryRequest = addTokenToRequest(originalRequest, newToken);

            log.info("Token刷新成功，重试请求");
            return chain.proceed(retryRequest);

        } catch (Exception e) {
            log.error("Token刷新失败，返回原始错误响应", e);
            // 返回原始401响应，避免无限重试
            return new Response.Builder()
                    .request(originalRequest)
                    .protocol(Protocol.HTTP_1_1)
                    .code(401)
                    .message("Unauthorized")
                    .body(ResponseBody.create( MediaType.parse("text/plain"),"Token refresh failed"))
                    .build();
        }
    }


}
